package com.jtny.nytb.equipment.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jtny.component.core.util.PageUtils;
import com.jtny.component.core.util.QueryWrapperUtils;
import com.jtny.component.entity.PageData;
import com.jtny.component.util.Assert;
import com.jtny.component.util.BeanUtils;
import com.jtny.nytb.equipment.dao.instrument.InstrumentDAO;
import com.jtny.nytb.equipment.domain.instrument.InstrumentDO;
import com.jtny.nytb.equipment.dto.instrument.QueryInstrumentDTO;
import com.jtny.nytb.equipment.dto.instrument.RequestInstrumentDTO;
import com.jtny.nytb.equipment.dto.instrument.ResponseInstrumentDTO;
import com.jtny.nytb.equipment.service.InstrumentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 智慧能源中心-伍天宇
 * @version 1.0
 * @package com.jtny
 * @fileName InstrumentServiceImpl.java
 * @createTime 2024年01月12日 10:08
 * @Copyright© 2024 jtny
 * 江投能源技术研究院 版权所有
 */
@Service
public class InstrumentServiceImpl extends ServiceImpl<InstrumentDAO, InstrumentDO> implements InstrumentService {
    /**
     * 保存计量器具
     *
     * @param requestInstrumentDTO 计量器具
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseInstrumentDTO saveInstrument(RequestInstrumentDTO requestInstrumentDTO) {
        InstrumentDO toSave = BeanUtils.copyToObject(requestInstrumentDTO, InstrumentDO.class);
        Assert.isTrue(checkName(toSave.getInstrumentName(), null), "名称重复");
        saveOrUpdate(toSave);
        return BeanUtils.copyToObject(toSave, ResponseInstrumentDTO.class);
    }

    /**
     * 修改计量器具
     *
     * @param requestInstrumentDTO 计量器具
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseInstrumentDTO updateInstrument(RequestInstrumentDTO requestInstrumentDTO) {
        InstrumentDO instrumentDO = BeanUtils.copyToObject(requestInstrumentDTO, InstrumentDO.class);
        Assert.isTrue(checkName(instrumentDO.getInstrumentName(), instrumentDO.getId()), "名称重复");
        updateById(instrumentDO);
        return BeanUtils.copyToObject(instrumentDO, ResponseInstrumentDTO.class);
    }

    /**
     * 删除计量具
     *
     * @param id 计量具ID
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteInstrument(Long id) {
        return removeById(id);
    }

    /**
     * 查询计量具
     *
     * @param id 计量具ID
     * @return
     */
    @Override
    public ResponseInstrumentDTO getInstrument(Long id) {
        InstrumentDO instrumentDO = getById(id);
        Assert.notNull(instrumentDO, "计量器具不存在");
        return BeanUtils.copyToObject(instrumentDO, ResponseInstrumentDTO.class);
    }

    /**
     * 查询计量具
     *
     * @param queryInstrumentDTO 查询条件
     * @return
     */
    @Override
    public List<ResponseInstrumentDTO> listInstrument(QueryInstrumentDTO queryInstrumentDTO) {
        QueryWrapper<InstrumentDO> wrapper = QueryWrapperUtils.getQueryWrapper(queryInstrumentDTO);
        List<InstrumentDO> instrumentDOList = list(wrapper);
        return BeanUtils.copyToList(instrumentDOList, ResponseInstrumentDTO.class);
    }

    /**
     * 分页查询计量具
     *
     * @param queryInstrumentDTO 查询条件
     * @return
     */
    @Override
    public PageData<ResponseInstrumentDTO> pageInstrument(QueryInstrumentDTO queryInstrumentDTO) {
        QueryWrapper<InstrumentDO> wrapper = QueryWrapperUtils.getQueryWrapper(queryInstrumentDTO);
        wrapper.orderByDesc("id");
        // 分页查询用户信息
        Page<InstrumentDO> page = Page.of(queryInstrumentDTO.getPageNo(), queryInstrumentDTO.getPageSize());
        PageData<InstrumentDO> pageData = PageUtils.getPageData(this.baseMapper.selectPage(page, wrapper), queryInstrumentDTO);
        return pageData.transformData(ResponseInstrumentDTO.class);
    }

    @Override
    public List<ResponseInstrumentDTO> getByInstrumentNo(RequestInstrumentDTO requestInstrumentDTO) {
        List<InstrumentDO> list = new ArrayList<>();
        if (requestInstrumentDTO.getInstrumentNo() != null && !requestInstrumentDTO.getInstrumentNo().trim().equals("")){
            QueryWrapper<InstrumentDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("instrument_no", requestInstrumentDTO.getInstrumentNo());
            list = this.baseMapper.selectList(queryWrapper);
        }
        return BeanUtils.copyToList(list, ResponseInstrumentDTO.class);
    }

    @Override
    public List<ResponseInstrumentDTO> getAlarmInstrument(QueryInstrumentDTO queryInstrumentDTO) {
        QueryWrapper<InstrumentDO> qw = new QueryWrapper<>();
        qw.eq("detection_alarm", 1);
        List<Long> instrumentIds = queryInstrumentDTO.getInstrumentIds();
        if (CollUtil.isNotEmpty(instrumentIds)) {
            qw.notIn("id", instrumentIds);
        }
        List<InstrumentDO> list = this.list(qw);
        // 获取当前时间
        Date now = new Date();
        list = list.stream().filter(v -> {
            String calibrationCycle = v.getCalibrationCycle();
            Date calibrationLastTime = v.getCalibrationLastTime();
            LocalDate localDate = calibrationLastTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            if (calibrationCycle.contains("年"))  {
                calibrationCycle = calibrationCycle.substring(0, 1);
                localDate = localDate.plusYears(Integer.parseInt(calibrationCycle));
            } else {
                calibrationCycle = calibrationCycle.substring(0, 1);
                localDate =  localDate.plusMonths(Integer.parseInt(calibrationCycle));
            }
            Date from = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
            return from.before(now);
        }).collect(Collectors.toList());
        return BeanUtils.copyToList(list, ResponseInstrumentDTO.class);
    }

    /**
     * 校验名称是否重复
     *
     * @param name 名称
     * @param id   主键ID
     * @return {@link Boolean}
     */
    private Boolean checkName(String name, Long id) {
        if (StrUtil.isBlank(name)) {
            return Boolean.TRUE;
        }
        if (ObjectUtil.isEmpty(id)) {
            return !this.baseMapper.exists(Wrappers.<InstrumentDO>lambdaQuery()
                    .eq(InstrumentDO::getInstrumentName, name));
//                    .ne(InstrumentDO::getStatus, GenericStatusEnum.DELETED.getValue()));
        } else {
            return !this.baseMapper.exists(Wrappers.<InstrumentDO>lambdaQuery()
                    .eq(InstrumentDO::getInstrumentName, name)
//                    .ne(InstrumentDO::getStatus, GenericStatusEnum.DELETED.getValue())
                    .ne(InstrumentDO::getId, id));
        }
    }
}
